<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //this的值是运行时决定的，不是声明的时候决定的
      function Person(x) {
        this.name = 'x'
        console.log('person内this:', this)
      }

      //Person('def') //控制台输出window.person('def'),这里指的是整个全局变量，也就是window对象

      //这里输出的是this.name=x
      //在console.log中的this指的是this.name
      let p1 = new Person()
      //console.log(p1())

      //第二个案例
      var prop = 100
      const text = {
        prop: 1000,
        func: function () {
          return this.prop
        },
      }
      //下列代码中text.func()其中fun:function(){return this.prop}中的this指的是text中的prop：1000
      console.log(text.func())

      let f = text.func
      console.log('xxx:', f()) //window.f()
      //上列代码所输出的是window，因为text.func只是将其调用出来，
      //理解的技巧：方法是属于对象的，方法被调用，一定有一个对象点出来
      //那么函数内部的this的值就是点号左边的对象
      //window是全局对象
      console.log(this === window)
      a = 37
      console.log(window.a)
      this.b = 'MDN'

      //在非严格模式下使用 call 和 apply 时，如果用作 this 的值不是对象，则会被尝试转换为对象。null 和 undefined 被转换为全局对象。原始值如 7 或 'foo' 会使用相应构造函数转换为对象。因此 7 会被转换为 new Number(7) 生成的对象，字符串 'foo' 会转换为 new String('foo') 生成的对象。
      function add(c, d) {
        return this.a + this.b + c + d
      }
      //this.a和this.b指的是var o中的a:1和b:3
      var o = { a: 1, b: 3 }
      //add.call中o指的是this.a+this.b,5和8指的是add函数中形参的实际参数
      add.call(o, 5, 7)
      //结果输出16
      //console.log(add())
      add.apply(o, [10, 20]) //输出34
    </script>
  </body>
</html>
